package com.idanchuang.support.etcache;

import com.idanchuang.support.etcache.annotation.aop.CreateEtCacheAnnotationBeanPostProcessor;
import com.idanchuang.support.etcache.local.LocalCacheFactory;
import com.idanchuang.support.etcache.pressure.PressureChecker;
import com.idanchuang.support.etcache.pubsub.*;
import com.idanchuang.support.etcache.remote.RemoteCacheFactory;
import com.idanchuang.support.etcache.remote.codec.RemoteKeyCodec;
import com.idanchuang.support.etcache.support.jetcache.EtCacheJetCacheAutoConfiguration;
import com.idanchuang.support.etcache.support.spring.cache.EtCacheSpringCacheAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.data.redis.connection.RedisConnectionFactory;

/**
 * @author yjy
 * Created at 2021/12/27 10:35 下午
 */
@Configuration
@ConditionalOnEtCacheEnabled
@Import({EtCacheSpringCacheAutoConfiguration.class, EtCacheJetCacheAutoConfiguration.class})
@AutoConfigureAfter(EtCacheCoreAutoConfiguration.class)
public class EtCacheAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(EtCacheManager.class)
    public EtCacheManager etCacheManager(RemoteKeyCodec remoteKeyCodec,
                                         RemoteEventSubscriber subscriber,
                                         RemoteEventPublisher publisher,
                                         LocalCacheFactory localCacheFactory, RemoteCacheFactory remoteCacheFactory,
                                         PressureChecker pressureChecker, SubEventQueue subEventQueue, EtCacheProperties properties) {
        return new EtCacheManager(remoteKeyCodec, subscriber,
                publisher, localCacheFactory, remoteCacheFactory, pressureChecker, subEventQueue, properties);
    }

    @Bean
    @ConditionalOnMissingBean(RemoteEventHandler.class)
    public RemoteEventHandler remoteEventHandler(EtCacheManager manager, SubEventQueue subEventQueue) {
        return new DefaultRemoteEventHandler(manager, subEventQueue);
    }

    @Bean
    public CreateEtCacheAnnotationBeanPostProcessor createEtCacheAnnotationBeanPostProcessor() {
        return new CreateEtCacheAnnotationBeanPostProcessor();
    }

    @Bean
    @ConditionalOnMissingBean(RedisRemoteExpireSubscriber.class)
    public RedisRemoteExpireSubscriber redisRemoteExpireSubscriber(RedisConnectionFactory redisConnectionFactory, RemoteKeyCodec remoteKeyCodec, SubEventQueue subEventQueue)
            throws NoSuchFieldException, IllegalAccessException {
        return new RedisRemoteExpireSubscriber(redisConnectionFactory, remoteKeyCodec, subEventQueue);
    }
}
